package com.complex.javasecurity;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/** */
/**
 * DES安全编码组件 author by http://www.bt285.cn http://www.5a520.cn
 * 
 * 
 * 支持 DES、DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR) DES key size
 * must be equal to 56 DESede(TripleDES) key size must be equal to 112 or 168
 * AES key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be
 * available Blowfish key size must be multiple of 8, and can only range from 32
 * to 448 (inclusive) RC2 key size must be between 40 and 1024 bits RC4(ARCFOUR)
 * key size must be between 40 and 1024 bits 具体内容 需要关注 JDK Document
 * http:///docs/technotes/guides/security/SunProviders.html
 * 
 * 
 */
public abstract class DESCoder extends Coder {
	/** */
	/**
	 * ALGORITHM 算法 可替换为以下任意一种算法，同时key值的size相应改变。
	 * 
	 * 
	 * DES key size must be equal to 56 DESede(TripleDES) key size must be equal
	 * to 112 or 168 AES key size must be equal to 128, 192 or 256,but 192 and
	 * 256 bits may not be available Blowfish key size must be multiple of 8,
	 * and can only range from 32 to 448 (inclusive) RC2 key size must be
	 * between 40 and 1024 bits RC4(ARCFOUR) key size must be between 40 and
	 * 1024 bits
	 * 
	 * 
	 * 在Key toKey(byte[] key)方法中使用下述代码 SecretKey secretKey = new
	 * SecretKeySpec(key, ALGORITHM); 替换
	 * 
	 * DESKeySpec dks = new DESKeySpec(key); SecretKeyFactory keyFactory =
	 * SecretKeyFactory.getInstance(ALGORITHM); SecretKey secretKey =
	 * keyFactory.generateSecret(dks);
	 * 
	 */
	public static final String ALGORITHM = "DES";

	/** */
	/**
	 * 转换密钥
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static Key toKey(byte[] key) throws Exception {
		DESKeySpec dks = new DESKeySpec(key);
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
		SecretKey secretKey = keyFactory.generateSecret(dks);

		// 当使用其他对称加密算法时，如AES、Blowfish等算法时，用下述代码替换上述三行代码
		// SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);

		return secretKey;
	}

	/** */
	/**
	 * 解密
	 * 
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] data, String key) throws Exception {
		Key k = toKey(decryptBASE64(key));

		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, k);

		return cipher.doFinal(data);
	}

	/** */
	/**
	 * 加密
	 * 
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] data, String key) throws Exception {
		Key k = toKey(decryptBASE64(key));
		Cipher cipher = Cipher.getInstance(ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, k);

		return cipher.doFinal(data);
	}

	/** */
	/**
	 * 生成密钥
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String initKey() throws Exception {
		return initKey(null);
	}

	/** */
	/**
	 * 生成密钥
	 * 
	 * @param seed
	 * @return
	 * @throws Exception
	 */
	public static String initKey(String seed) throws Exception {
		SecureRandom secureRandom = null;

		if (seed != null) {
			secureRandom = new SecureRandom(decryptBASE64(seed));
		} else {
			secureRandom = new SecureRandom();
		}

		KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
		kg.init(secureRandom);

		SecretKey secretKey = kg.generateKey();

		return encryptBASE64(secretKey.getEncoded());
	}
}
